#! /usr/bin/env python
import opentick
import logging
from time    import sleep
from getpass import getpass

class SymbolListClient( opentick.OTClient ):
    """OTClient subclass used to login to the OpenTick servers and obtain a list
    of symbols for the New York Stock Exchange (code: N).
    """
    def __init__( self ):
        super( SymbolListClient, self ).__init__()
        #
        self.__mIsSymbolListReceived = False
        self.__mIsErrorEncountered   = False
        return 
        
    def IsSymbolListReceived( self ):
        return self.__mIsSymbolListReceived
        
    def IsErrorEncountered( self ):
        return self.__mIsErrorEncountered
        
    def onLogin( self ):
        logging.info( "Login successful." )
        #
        # Request the list of symbols associated with NYSE (code:N)
        #
        exchange_code = "N"
        logging.info( "Requesting list of symbols for exchange " + exchange_code )
        self.__mRequestId = self.requestListSymbols( exchange_code )
        return 
        
    def onListSymbols( self, 
                       symbolList ):
        #
        # Do nothing if the symbol list is empty.
        #
        if ( None == symbolList ) or ( 0 == len( symbolList ) ):
            logging.warning( "Empty symbol list received from OTFeed server." )
            return
        #
        # Display the list of symbols. 
        #            
        for symbol in symbolList:
            print "%-5s %-60s" % ( symbol.getCode(), symbol.getCompany() )           
        return
        
    def onMessage( self, 
                   otMessage ):
        OT_LIST_SYMBOLS = 10 
        if ( (otMessage.getRequestId() == self.__mRequestId ) and
             (OT_LIST_SYMBOLS == otMessage.getCode() ) ):
            #
            logging.info( "Complete symbol list received." )
            self.__mIsSymbolListReceived = True
        return
    
    def onError( self, otError ):
        logging.error( "[" + str(otError.getRequestId()) + ":" + str(otError.getCode() ) +
                       "] " + otError.getDescription() )
        self.__mIsErrorEncountered = True 
        return 
#
# Run the remaining lines if we are in the top-level script environment.
#
if __name__ == "__main__":
    logging.basicConfig( level  = logging.DEBUG,
                         format = '%(asctime)s %(levelname)s %(message)s' )
    #
    # Create an instance of our OpenTick client and add a server host.
    #
    client = SymbolListClient()
    client.addHost( "feed2.opentick.com", 10010 )
    #
    # Ask the user for a login account name and password to connect to the 
    # OpenTick server.
    #
    username = raw_input( "Enter the user name: " )
    password = getpass( "Password for " + username + ": " )
    #
    # Initiate login process. 
    #
    client.login( username, password )
    #
    # Wait for the client to request and receive the exchange list.
    #
    while ( ( not client.IsSymbolListReceived() ) and
            ( not client.IsErrorEncountered() ) ):
        sleep( 1 )
    #
